package com.wj.tool.common.utils;

import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.SystemUtils;

import java.net.Inet4Address;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;

public class UuidUtils {

    private long workerId;
    private static long offset = 0L;
    private static long lastEpoch = 0L;

    /**
     * 根据传入的时间表示格式，返回当前时间的格式 如果是yyyyMMdd，注意字母y不能大写。
     *
     * @param sformat
     *            yyyyMMddhhmmss
     * @return
     */
    public static String getDate(String sformat) {
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat(sformat);
        String dateString = formatter.format(currentTime);
        return dateString;
    }

    public static String getRandomNum(int num){
        String numStr = "";
        for(int i = 0; i < num; i++){
            numStr += (int)(10*(Math.random()));
        }
        return numStr;
    }
    /**
     * 生成id
     * @return
     */
    public static Long getGeneratID(){
        String sformat = "MMddhhmmssSSS";
        int num = 6;
        String idStr = getDate(sformat) + getRandomNum(num);
        Long id = Long.valueOf(idStr);
        return id;
    }

    public static Long createId(){
        return getNextId(timeGen());
    }

    private static long timeGen() {
        return System.currentTimeMillis() / 1000L;
    }

    private static synchronized long getNextId(long epochSecond) {
        if (epochSecond < lastEpoch) {
            epochSecond = lastEpoch;
        }

        if (lastEpoch != epochSecond) {
            lastEpoch = epochSecond;
            reset();
        }

        ++offset;
        long next = offset & 65535L;
        if (next == 0L) {
            return getNextId(epochSecond + 1L);
        } else {
            return generateId(epochSecond, next, getWorkId());
        }
    }


    private static void reset() {
        offset = 0L;
    }

    private static long generateId(long epochSecond, long next, long workerId) {
        return epochSecond - OFFSET << 21 | next << 6 | workerId;
    }

    private static final long OFFSET = LocalDate.of(2020, 1, 1).atStartOfDay(ZoneId.of("Z")).toEpochSecond();

    private static long getWorkId() {
        try {
            int[] ints = toCodePoints(Inet4Address.getLocalHost().getHostAddress());
            int sums = 0;
            int[] var2 = ints;
            int var3 = ints.length;

            for(int var4 = 0; var4 < var3; ++var4) {
                int b = var2[var4];
                sums += b;
            }

            return (long)(sums % 64);
        } catch (Exception var6) {
            return nextLong(0L, 63L);
        }
    }

    public static long nextLong(final long startInclusive, final long endExclusive) {
        return RandomUtils.nextLong(startInclusive, endExclusive);
    }

    public static int[] toCodePoints(CharSequence str) {
        return org.apache.commons.lang3.StringUtils.toCodePoints(SystemUtils.getHostName());
    }
}

